package servlet;

import it.polimi.swimv2.entities.User;
import it.polimi.swimv2.remote.AbilityManagerRemote;
import it.polimi.swimv2.remote.HelpSearchManagerRemote;
import it.polimi.swimv2.util.RemoteBindingName;

import java.io.IOException;
import java.util.Collection;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class HelpSearchServlet
 */
public class HelpSearchServlet extends HttpServlet {	
	
	
	
	//Jsp Pages
	private static final String LOGIN_FORM_JSP = "loginForm.jsp";
	private static final String INDEX_JSP = "index.jsp";
	private static final String SEARCH_FOR_HELP_JSP = "searchForHelp.jsp";
	private static final String ERROR_JSP = "error.jsp";
	private static final String SEARCH_RESULT_JSP = "searchResult.jsp";
	
	//Parameters in HTTP Request
	private static final String SEARCH_FOR_HELP = "searchForHelp";
	private static final String ACT = "act";
	private static final String SEARCH_FOR_HELP_FORM = "searchForHelpForm";
	private static final String USER = "user";
	
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelpSearchServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		manageRequest(request, response);
	}
	
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		manageRequest(request, response);
	}

	/**
	 * manages the action requested by http request
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void manageRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		
		String act= request.getParameter(ACT);
		if(act==null){
			response.sendRedirect(INDEX_JSP);
			return;
		}
		
		if(act.equals(SEARCH_FOR_HELP_FORM)){			
			showHelpSearchForm(request, response);
		}else if(act.equals(SEARCH_FOR_HELP)){
			manageSearch(request, response);
		}else{
			response.sendRedirect(INDEX_JSP);
		}
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void showHelpSearchForm(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		try{
			AbilityManagerRemote rem = retrieveAbilityManagerRemote();
			Collection<String> declarableAbilities = rem.getDeclarableAbilities();
			request.setAttribute("declarableAbilities", declarableAbilities);
			RequestDispatcher dispatcher = request.getRequestDispatcher(SEARCH_FOR_HELP_JSP);
			dispatcher.forward(request, response); 
		}catch (NamingException e){
			response.sendRedirect(ERROR_JSP); 
		}
	}	

	/**
	 * Manages the search and shows the results list
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void manageSearch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		
			try{
				HelpSearchManagerRemote rem = retrieveHelpSearchManagerRemote();
				if(request.getParameter("ability").equals("")){
					request.setAttribute("missAbility", "missed");
					showHelpSearchForm(request, response);
				}else{				
				Collection<User> foundUsers = manageSearchRequest(request, rem);
				request.setAttribute("searchResult", foundUsers);
				RequestDispatcher dispatcher = request.getRequestDispatcher(SEARCH_RESULT_JSP);
				dispatcher.forward(request, response); 
				}
			}catch (NamingException e){
				response.sendRedirect(ERROR_JSP); 
			}
	
	}
	
	 /**
	  * Retrieves the results list
	  * @param request
	  * @param rem
	  * @return
	  */
	private Collection<User> manageSearchRequest(HttpServletRequest request, HelpSearchManagerRemote rem) {
		HttpSession session = request.getSession();
		String username = (String) session.getAttribute(USER);
		String ability = request.getParameter("ability");
		String city = request.getParameter("city");
		if(request.getParameter("friendsOnly")!=null){
			return rem.searchFriendByAbility(username, ability, city);
		}else{
			return rem.searchByAbility(ability, city);
		}
	}
	
	/**
	 * Retrieves the remote object
	 * @return
	 * @throws NamingException
	 */
	private HelpSearchManagerRemote retrieveHelpSearchManagerRemote() throws NamingException {
		Context jndiContext = new InitialContext();
		Object ref = jndiContext.lookup(RemoteBindingName.HELP_SEARCH_MANAGER);
		return (HelpSearchManagerRemote) ref;
	}
	
	/**
	 * Retrieves the remote object
	 * @return
	 * @throws NamingException
	 */
	private AbilityManagerRemote retrieveAbilityManagerRemote() throws NamingException {
		Context jndiContext = new InitialContext();
		Object ref = jndiContext.lookup(RemoteBindingName.ABILITY_MANAGER);
		return (AbilityManagerRemote) ref;
	}
}
